Imports INIFile
'this program is not coded as well as I want it to be, however it is a working demo
'app that shows the main functionality of the INIFile class.

Public Class Form1
    'contain the actual INI file
    Public oINI As New INIFile.INIFile


    Private Sub tTabs_Selected(ByVal sender As Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles tTabs.Selected
        tINI.Text = oINI.Contents

        UpdateSections()
    End Sub

    Private Sub lSections_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lSections.SelectedIndexChanged
        UpdateKeys()
    End Sub

#Region "Button code for Toolbar"
    Private Sub bLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bLoad.Click
        ofd.ShowDialog(Me)

        Dim fiFile As New IO.FileInfo(ofd.FileName)

        Using srFile As IO.StreamReader = fiFile.OpenText
            tSource.Text = srFile.ReadToEnd()

            srFile.Close()
        End Using

        bParse_Click(sender, e)
    End Sub

    Private Sub bSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bSave.Click
        If MessageBox.Show("This will save the contents of the upper text area, not the bottom one. Continue?", Nothing, MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.Yes Then
            sfd.ShowDialog(Me)

            Dim fiFile As New IO.FileInfo(sfd.FileName)

            Using swFile As IO.StreamWriter = fiFile.CreateText
                swFile.Write(tINI.Text)

                swFile.Flush()
                swFile.Close()
            End Using
        End If
    End Sub

    Private Sub bParse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bParse.Click
        oINI.Contents = tSource.Text
        tINI.Text = oINI.Contents
    End Sub
#End Region

#Region "Button code for sections"
    Private Sub bAddSection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bAddSection.Click
        'running low on time. didn't implement adding of a 'top of file' section.
        'for that kind of section, set the name to Nothing. (Make sure this section
        'is always first in the array to avoid it being merged with the section above
        'it the next time it's parsed.)

        Dim sName As String = InputBox("New section's name?", , "section")
        Dim oSection As New Section(sName)

        oINI.Sections.Add(oSection)

        UpdateSections()

        lSections.SelectedItem = lSections.Items(lSections.Items.Count - 1)
    End Sub

    Private Sub bRemoveSection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bRemoveSection.Click

        oINI.Sections.Remove(CurrentSection)
        UpdateSections()
        UpdateKeys()
    End Sub
#End Region

#Region "Button code for keys"
    Private Sub bAddKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bAddKey.Click
        Dim sName As String = InputBox("Name of key? (Begin with ; to create a comment instead)")

        If sName.StartsWith(";") Then
            CurrentSection.Keys.Add(New Key(sName.Substring(1)))
        Else
            Dim sValue As String = InputBox("Value for '" & sName & "'?")

            CurrentSection.Keys.Add(New Key(sName, sValue))
        End If

        UpdateKeys()

        lKeys.SelectedItem = lKeys.Items(lKeys.Items.Count - 1)
    End Sub

    Private Sub bRemoveKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bRemoveKey.Click
        CurrentSection.Keys.Remove(CurrentKey)
        UpdateKeys()
    End Sub

    Private Sub bEditKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bEditKey.Click
        'It is also possible to convert a key to and from a comment
        'you'd think i'd implement it here, but i didn't...I'm lazy

        If CurrentKey.IsComment Then
            Dim sComment As String = InputBox("New comment text?", , CurrentKey.Value)

            CurrentKey.Value = sComment
            UpdateKeys()
        Else
            Dim sName As String = InputBox("New name of key?", , CurrentKey.Name)
            Dim sValue As String = InputBox("New value for '" & sName & "'?", , CurrentKey.Value)

            CurrentKey.Name = sName
            CurrentKey.Value = sValue

            UpdateKeys()
        End If
    End Sub
#End Region

#Region "UpdateSections/Keys"
    'Nice centralized updaters
    Sub UpdateSections()
        Dim oSection As Section

        lSections.Items.Clear()
        lKeys.Items.Clear()

        For Each oSection In oINI.Sections
            lSections.Items.Add(New SectionListItem(oSection))
        Next

        If oINI.Sections.Count = 0 Then
            Me.bRemoveSection.Enabled = False
            Me.bAddKey.Enabled = False
        Else
            Me.bRemoveSection.Enabled = True
            lSections.SelectedItem = lSections.Items(0)
            Me.bAddKey.Enabled = True
        End If
    End Sub

    Sub UpdateKeys()
        Dim oKey As Key

        lKeys.Items.Clear()

        If (CurrentSection() IsNot Nothing) Then
            If CurrentSection.Keys.Count = 0 Then
                Me.bEditKey.Enabled = False
                Me.bRemoveKey.Enabled = False
            Else
                Me.bEditKey.Enabled = True
                Me.bRemoveKey.Enabled = True

                For Each oKey In CurrentSection.Keys
                    lKeys.Items.Add(New KeyListItem(oKey))
                Next

                lKeys.SelectedItem = lKeys.Items(0)
            End If
        Else
            Me.bEditKey.Enabled = False
            Me.bAddKey.Enabled = False
            Me.bRemoveKey.Enabled = False
        End If
    End Sub
#End Region

#Region "CurrentSection/Key"
    'Makes the code easier on the eyes
    Function CurrentSection() As Section
        If lSections.SelectedItem Is Nothing Then
            Return Nothing
        Else
            Return DirectCast(lSections.SelectedItem, SectionListItem).Section
        End If
    End Function

    Function CurrentKey() As Key
        If lKeys.SelectedItem Is Nothing Then
            Return Nothing
        Else
            Return DirectCast(lKeys.SelectedItem, KeyListItem).Key
        End If
    End Function
#End Region

End Class

#Region "Classes for storing sections and keys. (Provides customized ToString method)"
'lets me easily show cutom text in the listbox (listboxes get the text from the ToString 
'method and I didn't want to hardwire any specific behavior into the INIFile class.)

Public Class SectionListItem
    Public Overrides Function ToString() As String
        If Section.Name Is Nothing Then
            Return "No Section"
        Else
            Return "==" & Section.Name & "==" '==Section Name==
        End If
    End Function

    Public Section As Section

    Public Sub New(ByVal SectionRef As Section)
        MyBase.New()

        Section = SectionRef
    End Sub
End Class

Public Class KeyListItem
    Public Overrides Function ToString() As String
        If Key.IsComment Then
            Return "Comment: " & Key.Value '"Comment: Value"
        Else
            Return "Key: '" & Key.Name & "'  Value: '" & Key.Value & "'" ' "Key: 'Name'  Value: 'Value'"
        End If
    End Function

    Public Key As Key

    Public Sub New(ByVal KeyRef As Key)
        MyBase.New()

        Key = KeyRef
    End Sub
End Class
#End Region